﻿namespace JoinBox.IO;

using System;
using System.IO;
using System.Text;


public static class EncodingHelper
{
    public static Encoding[] Encodings = new Encoding[]
    {
        new UTF8Encoding(),// 无签名
        new UTF7Encoding(),
        new UTF32Encoding(),
        Encoding.Default,
        Encoding.Unicode,
        Encoding.BigEndianUnicode,
        Encoding.UTF7,
        Encoding.UTF8,// 有签名
        Encoding.UTF32
    };
}


public class IBoxJson<RootType> where RootType : new()
{
    public Encoding? FileEncoding;
    public RootType? Root;
    public string? FullName;

    public virtual void Read()
    {
        if (FullName is null || !File.Exists(FullName))
            throw new Exception("文件不存在" + FullName);

        string json;
        FileStream? fileStream = null;
        StreamReader? streamReader = null;
        try
        {
            fileStream = new FileStream(FullName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);// FileShare才能进c盘
            foreach (var item in EncodingHelper.Encodings)
            {
                streamReader = new StreamReader(fileStream, item);
                json = streamReader.ReadToEnd();
                if (string.IsNullOrEmpty(json))
                    continue;

                // 反序列化*字符串转类
#if !NET50
                Root = JsonConvert.DeserializeObject<RootType>(json);
#else
                Root = JsonSerializer.Deserialize<RootType>(json);
#endif
                FileEncoding = item;
                break;

            }
        }
        finally
        {
            fileStream?.Dispose();
            streamReader?.Dispose();
        }
    }

    /// <summary>
    /// 保存文件
    /// </summary>
    public virtual void Save()
    {
        if (Root is null)
            throw new ArgumentNullException(nameof(Root));
        if (FullName is null)
            throw new ArgumentNullException(nameof(FullName));

        // 防止原有配置文件丢失,先把原有文件改名,然后生成一个新的配置,再删除原有的
        string? reName = null;
        if (File.Exists(FullName))
            reName = FileHelper.RenameFile(FullName);// 改名称

        if (FileEncoding is null)
            return;

        // 序列化*类转字符串
#if !NET50
        var serializeObject = JsonConvert.SerializeObject(Root, Formatting.Indented);
#else
        var serializeObject = JsonSerializer.Serialize(Root);
#endif
        File.WriteAllText(FullName, serializeObject, FileEncoding);

        if (reName is not null)
            File.Delete(reName);// 删除原有
    }

    /// <summary>
    /// 创建文件
    /// </summary>
    public virtual void Create()
    {
        if (FullName is null)
            throw new ArgumentNullException(nameof(FullName));

        var file = new FileStream(FullName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
        file.Close();
        Root = new RootType();
        Save();
    }
}
